#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
class String
{
public:
    String()
    :_pstr(new char[1])
    {
        
    }
    String(const char *s)
        : _pstr(new char[strlen(s) + 1]())
    {
        strcpy(_pstr, s);
    }
    String(const String &s)
        : _pstr(new char[strlen(s._pstr) + 1]())
    {
        strcpy(_pstr, s._pstr);
    }
    ~String()
    {
        if (_pstr != nullptr)
        {
            delete[] _pstr;
            _pstr = nullptr;
        }
    }
    String &operator=(const String &rhs)
    {
        if (this != &rhs)
        {
            delete[] _pstr;
            _pstr = new char[strlen(rhs._pstr) + 1]();
            strcpy(_pstr, rhs._pstr);
        }
        return *this;
    }
    String &operator=(const char *s)
    {
        // 字符串为空
        if (s == nullptr)
        {
            delete[] _pstr;
            _pstr = new char[1]();
            _pstr[0] = '\0';
            // 防止自赋值
        }
        else if (this->_pstr != s)
        {
            delete[] _pstr;
            _pstr = new char[strlen(s) + 1]();
            strcpy(_pstr, s);
        }
        return *this;
    }

    String &operator+=(const String &rhs)
    {
        char *temp = new char[strlen(rhs._pstr) + strlen(_pstr) + 1]();
        strcpy(temp, _pstr);
        strcat(temp, rhs._pstr);
        delete[] _pstr;
        _pstr = temp;
        return *this;
    }
    String &operator+=(const char *s)
    {
        if (s == nullptr)
        {
            return *this;
        }
        char *temp = new char[strlen(s) + strlen(_pstr) + 1]();
        strcpy(temp, _pstr);
        strcat(temp, s);
        delete[] _pstr;
        _pstr = temp;
        return *this;
    }

    char &operator[](std::size_t index)
    {
        if (index < strlen(_pstr) - 1)
        {
            return _pstr[index];
        }
        else
        {
            cout << "out of range" << endl;
            static char nullchar = '\0';
            return nullchar;
        }
    }
    const char &operator[](std::size_t index) const
    {
        if (index < strlen(_pstr) - 1)
        {
            return _pstr[index];
        }
        else
        {
            cout << "out of range" << endl;
            static char nullchar = '\0';
            return nullchar;
        }
    }

    std::size_t size() const{
        return strlen(_pstr);
    }
    const char *c_str() const{
        return _pstr;
    }

    friend bool operator==(const String & s1, const String & s2){
        return strcmp(s1._pstr,s2._pstr) == 0;
    }
    friend bool operator!=(const String & s1, const String & s2){
        return strcmp(s1._pstr,s2._pstr) !=0;
    }

    friend bool operator<(const String & s1, const String & s2){
        return strcmp(s1.c_str(),s2.c_str()) < 0;
    }
    friend bool operator>(const String & s1, const String & s2){
        return strcmp(s1.c_str(),s2.c_str()) > 0;
    }
    friend bool operator<=(const String & s1, const String & s2){
        return strcmp(s1.c_str(),s2.c_str()) <= 0;
    }
    friend bool operator>=(const String &s1, const String &s2){
        return strcmp(s1.c_str(),s2.c_str()) >= 0;
    }
    //输出流
    friend std::ostream &operator<<(std::ostream &os, const String &s){
        os << s._pstr;
        return os;
    }
    //输入流
    friend std::istream &operator>>(std::istream &is, String &s){
        //直接流向指针，原指针可能有原值，所以要初始化
        if(s._pstr){
            delete[]s._pstr;
        }
        //因为不确定用户要输入多少数据使用vector来接收数据
        vector<char> _input;
        char c;
        while ((c = is.get())!= '\n')
        {
            //每次从is中读取一个字符，读到换行符说明输入结束
            _input.push_back(c);
        }
        //申请堆空间，然后将数据存入堆空间
        char * temp = new char[_input.size() + 1]();
        for(size_t i = 0; i<_input.size();++i){
            temp[i] = _input[i];
        }
        s._pstr = temp;
        return is;
        
    }

private:
    char *_pstr;
};

String operator+(const String & s1, const String & s2){
    String temp(s1);
    temp +=s2;
    return temp;
}
String operator+(const String & s1, const char * s2){
    String temp(s1);
    temp+=s2;
    return temp;
}
String operator+(const char *s1, const String &s2){
    String temp(s1);
    temp +=s2;
    return temp;
}
void test()
{
    String s1("Hello");
    s1 = "world";
    String s2 = "World";
    s2+=s1;
    cout<<s2<<endl;
    String s3 = s2;
    cout <<s3<<endl;
    s3 +=s3;
    cout<< s3 << endl;

    const String s4 = "Hello World";
    cout<<s4[3]<<endl;
}
void test2(){
    String s;
    cin>>s;
    cout<<s<<endl;
}

int main()
{
    test2();
    return 0;
}
